Apprendre à utiliser Git en tant qu’utilisateur de R
09/04/2024
Le versioning consiste à conserver la version d’une entité logicielle quelconque de façon à pouvoir la retrouver facilement même après l’apparition et la mise en place de versions plus récentes.
Exemple de ce que l’on peut trouver sur un server :
Le versioning permet de :
Avec une forge, il permet en plus de :
=> Un usage qui se justifie même quand on est tout seul sur un projet !
Parmi les logiciels de versioning existants, Git est le plus populaire depuis quelques années :
What are the primary version control systems you use?
Source : Stackoverflow
Git est un logiciel libre de versioning.
Créé en 2005 par Linus Torvalds et utilisé pour le code source de Linux.
Codé en C
Plus de 1 200 000 commits en mars 2024 !
Source : Wikipédia
On versionne les fichiers de type texte
Par exemple :
Éventuellement, on peut aussi versionner des images si on en a besoin dans une application ou une documentation.
TOUT LE RESTE :)
C’est-à-dire notamment les fichiers tableurs, de traitements de texte, les pdf, les diaporamas de type powerpoint ou impress, les fichiers spécifiques aux projets R…
Pour se faciliter la tâche, on utiliser un fichier spécifique .gitignore situé le plus souvent à la racine des projets.
Il s’agit d’un fichier texte, qui liste les fichiers et dossiers (sous forme d’expressions régulières) à ne pas versionner.
– une ligne = une règle ;
– on peut ignorer :
• des fichiers
• des dossiers
• des extensions
• …
Si vous utiliser le package R gitssp mis à disposition des agents du MASA, voici ce qui est exclu par défaut avec la fonction gitssp::creer_gitignore() :
.Rproj.user
.Rhistory
.RData
.Renviron
.Ruserdata
/* Les fichiers avec ces extensions
*.xls
*.xlsx
*.ods
*.pdfF
*.docx
*.odt
*.ppt
*.odp
Si vous travaillez avec Cerise, Git est déjà installé.
=> Vous pouvez directement commencer à l’utiliser. (il vous faudra simplement régler votre configuration pour faire en sorte de dialoguer avec la forge interne Gitlab => voir ici)
Si vous travaillez en local, consultez cette procédure interne au MASA
Pré-requis : pour pouvoir utiliser correctement Git avec l’IDE RStudio, il convient d’utiliser le mode projet.
.git Note
Pensez à cocher la case
=> Une utilisation de Git en cliquant sur les boutons de RStudio
Pour cela, il vous suffit de vous placer dans le bon répertoire (par exemple avec la commande cd pour change directory).
Vous pouvez alors soit utiliser la même méthode qu’en local avec la commande cd soit de préférence :
Plus en haut à droite=> Une utilisation de Git en tapant des commandes qui commencent par git…
gitssp Un package à installer et chargé comme d’habitude.
Pour l’instant, les sources ne sont présentes que sur la forge interne du MASA :
remotes::install_git("https://forge.agriculture.rie.gouv.fr/gitlab/ssp/bmis/gitssp",
dependencies = T,
git = "external")Par exemple, pour tester si un dossier est versionné avec Git, on peut utiliser la fonction git_projet_existe() qui teste l’existence d’un fichier .git dans le répertoire courant.
Créer un nouveau projet puis choisir un nouveau répertoire :
Après avoir choisi le nom du nouveau projet, cocher la case “Créer un répôt git” :
La commande git init permet d’initialiser un dossier avec Git
Cette commande crée un nouveau sous-répertoire nommé .git qui contient tous les fichiers nécessaires au dépôt — un squelette de dépôt Git.
Pour l’instant, aucun fichier n’est encore versionné !
Important
Il s’agit d’être vigilant sur l’emplacement du terminal au moment du lancement de la commande git init au risque d’initialiser le mauvais répertoire !
Astuce
Lors de l’initialisation du dépôt Git, on peut directement choisir le nom de la branche avec la commande git init --initial-branch=<nom-de-branche>.
=> voir partie 4 de ce support
Le package R {gitssp} permet d’initialiser un dossier local avec Git tout en le synchronisant avec une forge.
Cela sera abordé dans la partie 4 de cette formation.
Note
D’autres packages comme {usethis} ou {gert} permettent de manipuler Git avec des fonctions R. Vous trouverez leurs liens dans la partie bibliographique de ce support
*Source : itnext.io
Pour évoquer le fonctionnement de Git et son articulation avec une forge, cela nécessite d’apprendre à utiliser de nouveaux termes (voir lexique diapo suivante).
working directory : répertoire de travail de l’agentstaging area ou index : zone tampon dans laquelle l’agent regroupe les changements en vue du prochain commit.local repository : dépôt local présent dans votre espace de travail (.git)remote repository : dépôt distant sur une forgegit add : ajout des changements à l’indexgit commit : enregistre les changements placés dans l’indexgit push : envoie les changements vers le dépôt distantgit pull : télécharge les changements depuis le dépôt distantgit checkout : permet de se déplacer dans l’arbre (retour vers le passé, changement de branche)Source : Allison Horst
Il s’agit de notre copie de travail c’est-à-dire le répertoire et sous-répertoires dans lesquels se trouvent les fichiers suivis par Git.
C’est là que l’agent effectue les changements sur les fichiers.
Il correspond à votre espace de travail.
Avis aux utilisateurs novices
Faire très attention au début de l’utilisation de Git : en fonction de la commande Git que vous allez utiliser (par exemple un git checkout pour changer de branche ou revenir dans le passé), Git va changer le contenu de cet espace sans vous avertir.
Zone tampon dans laquelle l’agent regroupe les changements en vue du prochain commit.
L’agent peut ajouter ou retirer les changements à l’index.
Il peut faire cela en une seule ou plusieurs opérations (voir diapos suivantes).
Attention
Ajouter des changements à plusieurs fichiers en même temps nécessite d’être sûr de ce que l’on fait et d’avoir correctement configuré le fichier .gitignore (voir diapositive suivante).
Pour ajouter des changements :
Avec RStudio
Un seul fichier : en cochant un fichier dans l’onglet Git
Plusieurs fichiers : en cochant plusieurs fichiers dans l’onglet Git
En ligne de commande :
git add <file-name>git add .Pour retirer des changements :
Avec RStudio
En décochant les fichiers dans l’onglet Git
En ligne de commande :
git reset <file-name>git resetL’onglet de RStudio permet d’avoir des repères visuels sur les changements apportés à chacun de vos fichiers :
Deleted : le fichier a été supprimé du working directoryModified : le contenu du fichier a été modifiéUntracked : le fichier a été ajouté au working directory et Git ne l’a jamais vu auparavantLa commande git status affiche l’état du working directory et de l’index.
Voici un exemple d’équivalence entre les icônes RStudio et le résultat renvoyé par la commande git status :
Après l’ajout de fichier à l’index, 2 nouvelles icônes apparaissent dans RStudio (même fonctionnement avec le terminal) :
Added : Git comprend que vous voulez ajouter le fichier au dépôtRenamed : Git comprend que le fichier a été renommé| Changement | AVANT l’ajout à l’index | APRÈS l’ajout à l’index |
|---|---|---|
| Ajout de fichier | ||
| Renommage de fichier |
“À chaque fois que vous validez ou enregistrez l’état du projet dans Git, il prend un”snapshot” du contenu de votre working directory à ce moment et enregistre une référence à ce snapshot. Pour être efficace, si les fichiers n’ont pas changé, Git ne stocke pas le fichier à nouveau, juste une référence vers le fichier original qu’il a déjà enregistré.”
L’interface de RStudio permet de rapidement et facilement visualiser les changements que vous avez apportés sur le code.
Pour cela cliquez sur le bouton diff de l’onglet Git .
La commande git diff affiche les différences.
Pour afficher les différences sur les fichiers déjà ajoutés à l’index, la commande est git diff --staged.
Le terminal permet d’aller plus loin dans l’observation des différences, par exemple en comparant 2 commits…
Dans RStudio cliquez sur le bouton Plus de l’onglet Git puis choisir le bouton Inverser :
Un message de confirmation vous demande si vous êtes sûr de votre action :
La commande git restore permet de restaurer des fichiers
| Action | Commande |
|---|---|
| Inverser les changements pas encore ajoutés à l’index | git restore <file-name> |
| Inverser les changements déjà ajoutés à l’index | git restore --staged <file-name> |
Action de figer l’état du dépôt sous forme de snapshot
Un bon commit :
Erreur courante du débutant sur Git :
git add .Il informe les utilisateurs :
D’après Conventional Commits, l’écriture des messages de commits devrait suivre la la structure minimale suivante :
<type>: <description>
Le tableau suivant reprend les types les plus couramment utilisés :
| Type Detail | Detail |
|---|---|
| wip | Développement d’une fonctionnalité |
| feat | Ajout d’une fonctionnalité |
| fix | Correction d’un bug/erreur |
| doc | Documentation |
| deprecated | Fonctionnalité dépréciée |
| chore | Tâches de routine/automatisées |
Après avoir ajouté les fichiers modifiés à l’index, il est temps de “committer” les changements c’est-à-dire de prendre une photo / un snapshot de ces fichiers modifiés.
Dans RStudio, il faut cliquer sur le bouton “Commit” de l’onglet “Git”
Puis, renseigner dans la nouvelle fenêtre qui s’affiche le message du commit et cliquer sur le bouton “Commit” :
La commande git commit -m "message du commit" permet à la fois de faire le commit tout en renseignant le message associé
Voici un exemple :
git commit -m "fix: ajout fichier odt dans .gitignore"
::: callout-note La commande git commit propose de nombreuses options qui sont disponibles ici. :::
Il y a au moins deux raisons de revenir sur un commit :
Cocher la case Amend previous commit en dessous du message de commit précédent.
La commande à utiliser est :
git commit --amend -m 'Mon nouveau message de commit'
Attention ! Cette commande ne doit être effectuée que si vous n’avez pas encore poussé le commit sur dépôt distant sinon les autres utilisateurs du commit seront affectés puisque le SHA-1 est changé
| Action | ||
|---|---|---|
| Vous ajoutez vos fichiers à l’index | Cochez les fichiers | git add |
| Vous committez vos changements | Appuyez sur le bouton “Commit” et vous renseignez votre message de commit | git commit - m "Votre message" |
| Vous envoyez vos commits en local sur le serveur distant | Appuyez sur le bouton “Push” | git push origin <nom-de-branche> |
| Supplément si vous travaillez à plusieurs : | ||
| Récupérer les éventuels commits de vos collègues | Appuyez sur le bouton “Pull” | git pull origin <nom-de-branche> |
En cliquant sur le bouton Historique de RStudio :
Ce qui permet d’accéder à la fenêtre suivante :
RStudio permet facilement de :
Balayer l’historique du projet en sélectionnant les différents commits.
Accèder aux informations correspondants à chaque commit.
Cliquer sur les fichiers concernés par chaque commit et afficher leur état au moment choisi.
Avec la commande
git log : Exemple :
C:\Users\damien.dotta\DEMESIS\Formations_Git\formation_git_2024>git log
commit efb2b38f3f4c7719201119c5bf1dea575e0621ab (HEAD -> main, origin/main)
Author: Damien Dotta <damien.dotta@live.fr>
Date: Fri Mar 29 17:13:00 2024 +0100
doc: ajout de ce qu'on versionne et ceux qu'on ne versionne pas
Ce qu’on y trouve :
Note
La commande git log --oneline affiche les informations concernant l’historique de façon plus compacte mais moins riche.
Quelle fréquence pour les commit ?
Aussi souvent que possible
Regrouper les modifications en lots qui “font sens”, avec un message pertinent qui résume bien les modifications apportées
Il ne faut committer sur la base du temps passé mais plutôt sur la base des fonctionnalités.
Convention
Par défaut, le dépôt distant porte l’alias origin
Définition Wikipédia :
En informatique, une forge est un système de gestion et de maintenance collaborative de texte.
C’est un espace où on peut archiver du code informatique (R mais pas que bien sûr) qui offre des fonctionnalités supplémentaires à Git comme :
Les plus connues : Gitlab, Github, Bitbucket…
Une forge peut être interne ou externe à un ministère.
URL de la forge interne du MASA : https://forge.agriculture.rie.gouv.fr/gitlab/
URL de la forge interne du MTECT : https://gitlab-forge.din.developpement-durable.gouv.fr/
URL du MTECT sur Github : https://github.com/MTES-MCT
À retenir !
Pour travailler avec Gitlab, il faut mettre en place un mode d’authentification.
2 modes principaux existent :
SSHHTTPSAu MASA, une procédure de configuration existe et a été validée en mars 2024 pour établir la connexion entre Cerise et la forge gitlab interne. Celle-ci est basée sur le mode HTTPS et utilise le credential helper de Git qui évite d’avoir à re-saisir son mot de passe (ou token) à chaque action.
Aperçu des groupes au MASA/SSP :
Ce qu’il faut retenir :
| Rôle | Permissions |
|---|---|
| Owner | Les propriétaires ont un contrôle total sur le projet ou le groupe. |
| Maintainer | Les mainteneurs ont généralement des droits similaires aux propriétaires, mais ils n’ont pas accès à l’intégralité des paramètres du projet/groupe. |
| Developer | Les développeurs ont des droits d’écriture sur le projet ou le groupe. |
| Reporter | Les rapporteurs ont des droits de lecture sur le projet ou le groupe. |
| Guest | Les invités ont des droits d’accès limités et sont souvent utilisés pour donner un accès en lecture seule à des personnes extérieures au projet. |
Une issue est une tâche à effectuer : il peut s’agir tout autant de correctifs à apporter au projet que de fonctionnalités à ajouter.
Ouvrir une issue depuis Gitlab permet de :
– Discuter un point : il est possible d’échanger à plusieurs dans une issue pour définir comment la traiter.
– Assigner une tâche à une personne : lorsqu’on crée une issue, on peut assigner la tâche à une ou plusieurs personnes. Elle s’affiche alors sur le tableau de bord.
– Définir une échéance, classer une issue avec un label : le tableau de bord permet alors d’avoir une vision complète des issues en cours.
Par défaut, les issues ne sont pas activées à la création d’un dépôt sur la forge Gitlab du MASA.
Pour les activer, il faut :
Settings dans le bandeau de gauche puis GeneralVisibility, project features, permissions
Puis renseigner les informations concernant l’issue.
Si vous utilisez des labels pour classer vos issues, Gitlab propose un affichage sous forme de tableau de bord qui permet de faire un suivi de projet sous forme de tâches.
Exemple :
1ère étape commune à toutes les méthodes : création d’un dépôt vide sur la forge Gitlab
Créer un nouveau projet, puis choisir “Contrôle de version” :
Puis choisir “Git” :
Puis renseigner :
La méthode à utiliser est différente selon les cas :
À retenir
Pour vérifier qu’un dépôt local est lié à un dépôt distant, la commande git remote -v est très utile car elle renvoit l’URL du dépôt distant s’il existe.
CAS 1 : création d’un nouveau répertoire
git clone <URL-depot-distant>Par exemple :
git clone https://forge.agriculture.rie.gouv.fr/gitlab/damien.dotta/test.git - Ouvrir le nouveau répertoire et commencer à y travailler comme d’habitude en y créant un projet, des scripts…
CAS 2 : un répertoire existe déjà
git remote add origin <URL-depot-distant>Par exemple :
git remote add origin https://forge.agriculture.rie.gouv.fr/gitlab/damien.dotta/test.git
Le package gitssp peut également être utilisé pour effectuer la liaison.
Avantage : plusieurs branches distantes (developpement, recette et production) vont être créées en une seule instruction R.
Inconvénient : il y a 1 étape supplémentaire dans les pré-requis.
library(git=ssp)ajouter_git()La fonction ajouter_git() comprend 2 arguments :
origin : URL du dépôt distant (obligatoire)dossier : chemin vers le projet .Rproj que vous avez crée (facultatif car Si aucun dossier n’est précisé, les opérations vont se dérouler dans le dossier courant)Par exemple :
Après avoir ajouté vos changements à l’index et fait vos commits, vous pouvez “pousser” ces modifications sur la forge avec RStudio.
Dans l’exemple ci-dessous, après avoir committer une fois, RStudio me prévient dans l’onglet “Git” que je suis sur la branche developpement d’un commit :
Pour pousser ce commit sur le dépôt distant, il suffit simplement de cliquer sur le bouton
Voilà comment pousser vos modifications sur la forge avec le terminal :
git status pour récupérer l’information de la situation de notre dépôt local par rapport au dépôt distant.git push pour pousser ce commit sur le dépôt distant.git push et git pull Dans les slides précédentes, une utilisation succinte des instructions git push et git pull a été faite.
Pour être sûr de maîtriser vos interactions entre le dépôt local et le dépôt distant, il est recommandé d’utiliser la syntaxe plus complète sur le modèle suivant :
git push <alias> <nom-branche>git pull <alias> <nom-branche>Exemples :
- git push origin developpement
- git pull origin production
Pour récupérer sur le dépôt local des changements qui ont été poussés sur le dépôt distant avec RStudio.
Exemples de cas d’usage :
- Si un membre de l’équipe projet a poussé des modifications avant vous sur le dépôt distant.
- Si vous voulez récupérer les dernières modifications apportées à la branche distante suite à une merge request (voir plus loin)
Pour récupérer les commits depuis le dépôt distant, il suffit simplement de cliquer sur le bouton
Dans le cas d’un travail en équipe, il s’agit d’une opération à faire très fréquemment.
Git vous empêchera de pousser vos modifications sur le dépôt distant si vous n’avez pas au préalable récupérer toutes les dernières modifications qui s’y trouvent.
Message qui s’affiche dans ce cas :
git pull pour récupérer les derniers commits depuis dépôt distant.Descendre en bas de la page puis :
Les tags sont des étiquettes qui pointent vers des points spécifiques dans l’historique de Git.
Ils sont très utiles pour étiqueter les versions de vos projets (v0.1, v0.2…).
Pour créer un tag v0.1 sur le dernier commit :
git tag -a v0.1 -m "Message de tag"
Pour créer un tag v0.1 a posteriori (avec l’ID du commit) :
git tag -a v0.1 0af8bfd9 -m "Message de tag"
Pour partager les tags sur le dépôt distant :
git push origin --tags
Pour lister les tags :
git tag
Il reste à faire un git pull pour récupérer le nouveau tag dans votre working directory.
L’interface de Gitlab permet de facilement se déplacer dans l’historique d’un projet versionné.
Par exemple :
Cliquer sur le commit d’intérêt et dans la fenêtre qui en détaille le contenu, cliquer sur “Browse file” :
On accède ainsi à l’état du projet tel qu’il était au moment du commit d’intérêt.
Remarque : des manipulations quasi-identiques permettent de faire la même chose avec les tags.
Pour revenir à la version du tag v0.1 :
git checkout v1.0
Pour revenir à la version du commit 0af8bfd9 :
git checkout 0af8bfd9
Pour remonter de 4 commits dans le passé :
git checkout nom-de-branche~4
Pour revenir au présent :
git checkout nom-de-branche
Note
Les instructions Git ci-dessus peuvent aussise décliner sur un fichier spécifique.
Par exemple avec la structure suivante pour un commit et un fichier particulier : git checkout commitID file-name
La commande git revert SHA-commit permet d’inverser/de défaire ce qui avait été fait au moment du commit d’intérêt.
Attention, le git revert crée un nouveau commit (d’inversion c’est-à-dire que les lignes ajoutées seront supprimées et les fichiers supprimés seront recréés…).
Il y a encore pleins d’instructions Git très utiles que vous découvrirez (ou pas) :
On crée une branche pour :
Concernant le noms des branches, une bonne pratique est d’utiliser la structure suivante : <categorie>-<nom>
| Catégorie | Signification |
|---|---|
| hotfix | Pour résoudre rapidement des problèmes critiques |
| bugfix | Pour résoudre des erreurs/bugs |
| feature | Pour ajouter/supprimer/modifier des fonctionnalités |
| test | Pour tester une idée expérimentale (hors issue) |
| issue-X | Pour faire référence à l’issue n°X |
Avec les forges Gitlab et Github, la fermeture des issues peut être automatiquement gérée via les messages de commit.
Pour cela, vous pouvez utiliser des mots-clés comme (au choix) :
- Close
- Fix
- Resolve
- Implement
En précisant le #numero-issue.
Exemple de message de commit :
feat: Ajout documentation utilisateurs
Close #31, en lien avec #29
Les branches permanentes persistent tout au long de la vie du projet.
Les branches temporaires :
RStudio indique la branche sur laquelle on se situe en haut à droite de l’onglet “Git” :
git status est la commande la plus simple
gitssp$get_current_branch()
Cliquer sur la petite flèche située à côté du nom de la branche courante :
git branch
git branch -a
gitssp$list_branch_local()
gitssp$list_branch_all()
Lorsqu’on affiche la liste des branches, la branche sur laquelle on se situe est identifiée avec un astérisque * devant.
Pour créer une nouvelle branche avec RStudio, il faut :
Cette procédure va créer la nouvelle branche à la fois sur le dépôt local mais aussi sur le dépôt distant.
Depuis l’interface Gitlab et à partir d’une issue, on peut créer une branche comme ci-dessous :
git pull dans le terminal ou RStudio.Pour créer une branche dans le dépôt local avec le terminal, les commandes git branch et git checkout sont utilisées.
Créer une nouvelle branche “bugfix” dans le dépôt local :
git branch bugfix
Créer une nouvelle branche “bugfix” dans le dépôt local et se placer dessus :
git checkout -b bugfix
Synchroniser la nouvelle branche locale “bugfix” avec la branche distante :
git push -u origin bugfix
Créer une nouvelle branche
gitssp$create_branch_local("nom-de-branche")
Pousser la branche locale sur le dépôt distant
gitssp$push_branch_gitlab("nom-de-branche")
Avec la commande dans le terminal :
git checkout nom-de-branche
Avec l’instruction R :
gitssp$switch_branch_local("nom-de-branche")
Avec l’IHM RStudio, on ne peut pas supprimer de branches locales.
Avec la commande dans le terminal :
git branch -d nom-de-branche
Avec l’instruction R :
gitssp$delete_branch_local("nom-de-branche")
Important
Git empêche la suppression de branche si vous êtes positionnés dessus. Dans ce cas, il faut au préalable changer de branche avec git checkout nom-de-branche
Avec l’IHM RStudio, on ne peut pas supprimer de branches distantes.
git push origin --delete nom-de-branche
gitssp$delete_branch_gitlab("nom-de-branche")
A VENIR
A VENIR
Les conflits surviennent généralement lorsque deux personnes ont modifié les mêmes lignes dans un fichier, ou si un développeur a supprimé un fichier alors qu’un autre développeur le modifiait. Dans ces cas, Git ne peut pas déterminer automatiquement la version correcte.
Les conflits n’affectent que le développeur qui effectue le merge, les autres membres de l’équipe ne sont pas conscients du conflit. Git marquera le fichier comme étant en conflit et arrêtera le processus de merge.
Il incombe alors aux développeurs de résoudre le conflit.
*Source: Atlassian
Exercice :
On se place dans la même configuration que dans l’application précédente : un mainteneur et deux/trois développeurs
Le mainteneur modifie le contenu de son fichier, puis commit et push les modifications
Sans faire de pull préalable, les développeurs modifient également le contenu du fichier du mainteneur, puis commit et push les modifications
Le push est rejeté pour la même raison que dans l’application précédente : les dépôts ne sont plus synchronisés, il faut pull les changements distants au préalable. Mais cette fois, le pull est également rejeté : il y a un conflit entre l’historique du projet distant et celui du projet local. Git nous indique qu’il faut résoudre le conflit avant de pouvoir modifier l’historique du projet.
Utiliser l’interface de RStudio pour résoudre le conflit, en choisissant la version du fichier que vous souhaitez conserver, puis commit/push les modifications
Comme dans l’application précédente, seul le développeur le plus rapide parvient à push. Les autres doivent répéter l’opération.
Pour délimiter la zone de conflit, Git utilise les annotations suivantes :
Quelques conseils :
En français :
En anglais :
2.4 Comment utiliser Git ?
3 façons seront présentées dans ce support :
Pour les commandes les plus courantes du quotidien
Pour les commandes plus avancées
gitsspPour simplifier l’articulation avec les dépôts distants